# Flask框架导入
from flask import render_template, redirect, url_for, request, flash

# 数据库导入
from inc.models import db

# 标准库导入
from datetime import datetime, timedelta
import logging
import traceback

# WTForms导入
from flask_wtf import FlaskForm
from wtforms import (
    StringField, TextAreaField, SelectField, HiddenField,
    IntegerField, DateField
)
from wtforms.validators import DataRequired, Optional, NumberRange

# 蓝图和装饰器导入
from . import task_bp
from ..utils import member_login_required, get_current_member

# 服务层函数导入
from . import services
from .services import (
    get_tasks, create_task, rate_task, get_project_members,
    get_task_detail, accept_task, start_task, update_task_progress,
    complete_task, assign_task, upload_attachment,
    download_attachment, delete_attachment
)
from inc.models import JiraTask, JiraStage

# --- 表单定义 ---

class TaskActionForm(FlaskForm):
    """用于执行任务操作的通用表单，主要用于CSRF保护"""
    csrf_token = HiddenField('CSRF Token')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 禁用CSRF验证，因为我们已经明确添加了csrf_token字段
        self.meta.csrf = False

class CreateTaskForm(FlaskForm):
    """创建和编辑任务的表单"""
    name = StringField('任务名称', validators=[DataRequired()])
    description = TextAreaField('任务描述')
    assignee_id = SelectField('负责人', coerce=int, validators=[DataRequired()])
    due_date = DateField('截止日期', format='%Y-%m-%d', validators=[Optional()])
    priority = SelectField('优先级', choices=[('high', '高'), ('medium', '中'), ('low', '低')], default='medium')
    project_id = HiddenField()


@task_bp.route('/create/<int:stage_id>', methods=['GET', 'POST'])
@member_login_required
def create(stage_id):
    """创建新任务"""
    current_member = get_current_member()
    stage = JiraStage.query.get_or_404(stage_id)
    members = get_project_members(stage_id)

    form = CreateTaskForm()
    form.assignee_id.choices = [(m['id'], m['name']) for m in members]
    form.project_id.data = stage.project_id

    if form.validate_on_submit():
        try:
            # 处理文件上传
            files = request.files.getlist('files')
            task = create_task(
                stage_id,
                current_member.id,
                form.data,
                files=files
            )
            flash('任务创建成功', 'success')
            # 修复：从后端对象获取 project_id，更可靠
            return redirect(url_for('member.jira.project_detail', project_id=task.stage.project_id))
        except (ValueError, PermissionError) as e:
            flash(str(e), 'danger')
        except Exception as e:
            flash('创建任务时发生未知错误', 'danger')
            logging.error(f"Task creation error: {str(e)}\n{traceback.format_exc()}")

    return render_template('member/task/create.html',
                           stage_id=stage_id,
                           form=form,
                           members=members)

@task_bp.route('/<int:task_id>/assign', methods=['POST'])
@member_login_required
def assign(task_id):
    """分配任务"""
    form = TaskActionForm()
    task = JiraTask.query.get_or_404(task_id)
    if form.validate_on_submit():
        try:
            assignee_id = request.form.get('assignee_id')
            assign_task(task_id, get_current_member().id, assignee_id)
            flash('任务已分配', 'success')
        except (ValueError, PermissionError) as e:
            flash(str(e), 'danger')
        except Exception as e:
            flash('分配任务失败', 'danger')
            logging.error(f"Task assign error: {str(e)}\n{traceback.format_exc()}")
    else:
        flash('无效的请求', 'danger')
    return redirect(url_for('member.task.task_detail', task_id=task_id))

@task_bp.route('/<int:task_id>/accept', methods=['POST'])
@member_login_required
def accept(task_id):
    """接受任务"""
    form = TaskActionForm()
    task = JiraTask.query.get_or_404(task_id)
    if form.validate_on_submit():
        try:
            accept_task(task_id, get_current_member().id)
            flash('任务已接受', 'success')
        except (ValueError, PermissionError) as e:
            flash(str(e), 'danger')
        except Exception as e:
            flash('接受任务失败', 'danger')
            logging.error(f"Task accept error: {str(e)}\n{traceback.format_exc()}")
    else:
        flash('无效的请求', 'danger')
    return redirect(url_for('member.task.task_detail', task_id=task_id))

@task_bp.route('/<int:task_id>/start', methods=['POST'])
@member_login_required
def start(task_id):
    """开始任务"""
    form = TaskActionForm()
    task = JiraTask.query.get_or_404(task_id)
    if form.validate_on_submit():
        try:
            start_task(task_id, get_current_member().id)
            flash('任务已开始', 'success')
        except (ValueError, PermissionError) as e:
            flash(str(e), 'danger')
        except Exception as e:
            flash('开始任务失败', 'danger')
            logging.error(f"Task start error: {str(e)}\n{traceback.format_exc()}")
    else:
        flash('无效的请求', 'danger')
    return redirect(url_for('member.task.task_detail', task_id=task_id))

@task_bp.route('/<int:task_id>/progress', methods=['POST'])
@member_login_required
def update_progress(task_id):
    """更新任务进度"""
    form = TaskActionForm()
    task = JiraTask.query.get_or_404(task_id)
    if form.validate_on_submit():
        try:
            progress = int(request.form.get('progress', 0))
            update_task_progress(task_id, get_current_member().id, progress)
            flash('任务进度已更新', 'success')
        except (ValueError, PermissionError) as e:
            flash(str(e), 'danger')
        except Exception as e:
            flash('更新进度失败', 'danger')
    else:
        flash('无效的请求', 'danger')
    return redirect(url_for('member.task.task_detail', task_id=task_id))

@task_bp.route('/<int:task_id>/complete', methods=['POST'])
@member_login_required
def complete(task_id):
    """完成任务"""
    form = TaskActionForm()
    task = JiraTask.query.get_or_404(task_id)
    if form.validate_on_submit():
        try:
            complete_task(task_id, get_current_member().id)
            flash('任务已完成', 'success')
        except (ValueError, PermissionError) as e:
            flash(str(e), 'danger')
        except Exception as e:
            flash('完成任务失败', 'danger')
    else:
        flash('无效的请求', 'danger')
    # 修复：从后端对象获取 project_id
    return redirect(url_for('member.jira.project_detail', project_id=task.stage.project_id))

class RateTaskForm(FlaskForm):
    """评价任务的表单"""
    rating = IntegerField('评分', validators=[DataRequired(), NumberRange(min=1, max=5)])
    comment = TextAreaField('评价内容')

@task_bp.route('/<int:task_id>/rate', methods=['POST'])
@member_login_required
def rate(task_id):
    """评价任务"""
    form = RateTaskForm()
    task = JiraTask.query.get_or_404(task_id)

    if form.validate_on_submit():
        try:
            # 权限检查已移至服务层
            rate_task(task_id, get_current_member().id, form.data)
            flash('任务评价已保存', 'success')
        except (ValueError, PermissionError) as e:
            flash(str(e), 'danger')
        except Exception as e:
            flash('评价任务失败', 'danger')
    else:
        # 将表单错误信息传递给模板
        for field, errors in form.errors.items():
            for error in errors:
                flash(f"{getattr(form, field).label.text} - {error}", 'danger')

    # 修复：从后端对象获取 project_id
    return redirect(url_for('member.jira.project_detail', project_id=task.stage.project_id))

@task_bp.route('/<int:task_id>')
@member_login_required
def task_detail(task_id):
    """任务详情"""
    current_member = get_current_member()
    task = get_task_detail(task_id)  # 需要确保get_task_detail函数在services.py中定义
    return render_template('member/task/detail.html', task=task, current_member=current_member)

@task_bp.route('/<int:task_id>/upload', methods=['POST'])
@member_login_required
def upload_attachment(task_id):
    """上传任务附件"""
    task = JiraTask.query.get_or_404(task_id)
    current_member = get_current_member()

    if 'file' not in request.files:
        flash('请选择文件', 'danger')
        return redirect(url_for('member.task.task_detail', task_id=task_id))

    try:
        file = request.files['file']
        description = request.form.get('description', '')
        from member.task.services import upload_attachment as service_upload_attachment
        service_upload_attachment(task_id, current_member.id, file, description)
        flash('附件上传成功', 'success')
    except (ValueError, PermissionError) as e:
        flash(str(e), 'danger')
    except Exception as e:
        flash('上传附件失败', 'danger')
        logging.error(f"Attachment upload error: {str(e)}\n{traceback.format_exc()}")

    return redirect(url_for('member.task.task_detail', task_id=task_id))

@task_bp.route('/attachment/<int:attachment_id>')
@member_login_required
def download_attachment(attachment_id):
    """下载任务附件"""
    try:
        from member.task.services import download_attachment
        return download_attachment(attachment_id, get_current_member().id)
    except (ValueError, PermissionError) as e:
        flash(str(e), 'danger')
        return redirect(request.referrer or url_for('member.task.list_tasks'))
    except Exception as e:
        flash(f'下载附件失败: {str(e)}', 'danger')
        logging.error(f"Attachment download error: {str(e)}\n{traceback.format_exc()}")
        return redirect(request.referrer or url_for('member.task.list_tasks'))

@task_bp.route('/attachment/<int:attachment_id>/check')
@member_login_required
def check_attachment(attachment_id):
    """检查附件是否存在"""
    from inc.models import TaskAttachment
    attachment = TaskAttachment.query.get(attachment_id)
    if not attachment:
        return {'exists': False}, 404
    return {'exists': True}, 200

@task_bp.route('/attachment/<int:attachment_id>/delete', methods=['POST'])
@member_login_required
def delete_attachment(attachment_id):
    """删除任务附件"""
    from flask import jsonify
    from inc.models import TaskAttachment

    form = TaskActionForm()
    if form.validate_on_submit():
        try:
            from member.task.services import delete_attachment as delete_attachment_service
            delete_attachment_service(attachment_id, get_current_member().id)
            return jsonify({
                'success': True,
                'message': '附件已删除'
            })
        except (ValueError, PermissionError) as e:
            return jsonify({
                'success': False,
                'message': str(e)
            }), 400
        except Exception as e:
            logging.error(f"Attachment delete error: {str(e)}\n{traceback.format_exc()}")
            return jsonify({
                'success': False,
                'message': '删除附件失败'
            }), 500
    else:
        return jsonify({
            'success': False,
            'message': '无效的请求'
        }), 400

@task_bp.route('/<int:task_id>/edit', methods=['GET', 'POST'])
@member_login_required
def edit(task_id):
    """编辑任务"""
    task = JiraTask.query.get_or_404(task_id)
    current_member = get_current_member()
    members = get_project_members(task.stage_id)

    # 权限检查：任务负责人或项目负责人可以编辑
    if (task.assignee_id != current_member.id and
        task.stage.project.owner_id != current_member.id):
        flash('只有任务负责人或项目负责人可以编辑任务', 'danger')
        return redirect(url_for('member.task.task_detail', task_id=task_id))

    form = CreateTaskForm()
    form.assignee_id.choices = [(m['id'], m['name']) for m in members]
    form.project_id.data = task.stage.project_id

    # 获取任务附件
    from inc.models import TaskAttachment
    attachments = TaskAttachment.query.filter_by(task_id=task_id).all()

    if request.method == 'GET':
        form.name.data = task.name
        form.description.data = task.description
        form.assignee_id.data = task.assignee_id
        form.due_date.data = task.due_date
        form.priority.data = task.priority

    if form.validate_on_submit():
        try:
            task.name = form.name.data
            task.description = form.description.data
            task.assignee_id = form.assignee_id.data
            task.due_date = form.due_date.data
            task.priority = form.priority.data

            # 处理文件上传
            files = request.files.getlist('files')
            for file in files:
                if file and file.filename:
                    from member.task.services import upload_attachment
                    upload_attachment(task_id, current_member.id, file, '任务编辑时上传')

            db.session.commit()
            flash('任务已更新', 'success')
            return redirect(url_for('member.task.task_detail', task_id=task_id))
        except (ValueError, PermissionError) as e:
            flash(str(e), 'danger')
        except Exception as e:
            flash('更新任务失败: ' + str(e), 'danger')
            logging.error(f"Task update error: {str(e)}\n{traceback.format_exc()}")

    return render_template('member/task/edit.html',
                           task=task,
                           form=form,
                           members=members,
                           attachments=attachments,
                           current_member=current_member)

@task_bp.route('/')
@member_login_required
def list_tasks():
    """我的任务列表"""
    current_member = get_current_member()
    status_filter = request.args.get('status', 'all')
    tasks = get_tasks(current_member.id, status_filter)
    now = datetime.now().date()
    return render_template('member/task/list.html', tasks=tasks, status_filter=status_filter, now=now)